﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TEAA
{
    public abstract class CatalogSystemManager
    {

        /// <summary>
        /// Make a backup on database catalog
        /// </summary>
        public abstract void BackupDatabaseCatalog();

        /// <summary>
        /// Restore backed up database catalog
        /// </summary>
        public abstract void RestoreDatabaseCatalog();

        /// <summary>
        /// Initialize a database catalog
        /// </summary>
        /// <param name="databaseRootLocation">Root location of database</param>
        /// <param name="databaseName">Name of the database</param>
        public abstract void InitializeDatabaseCatalog(string databaseRootLocation, string databaseName);

        /// <summary>
        /// Reload database catalog
        /// </summary>
        public abstract void ReloadDatabaseCatalog();

        /// <summary>
        /// Alter database
        /// </summary>
        /// <param name="newDatabaseName">New database name</param>
        public abstract void AlterDatabase(string newDatabaseName);

        /// <summary>
        /// Get database name
        /// </summary>
        /// <returns>Name of the database</returns>
        public abstract string GetDatabaseName();

        /// <summary>
        /// Get tables from catalog
        /// </summary>
        /// <returns>List of table names</returns>
        public abstract List<string> GetTables();

        /// <summary>
        /// Create new table in database catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="tableFileName">Name of the table file</param>
        public abstract void CreateTable(string tableName, string tableFileName);

        /// <summary>
        /// Alter an existing table in catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="newTableName">New name of the table</param>
        /// <param name="newTableFileName">New file of the table</param>
        public abstract void AlterTable(string tableName, string newTableName, string newTableFileName);

        /// <summary>
        /// Drop an existing table from catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        public abstract void DropTable(string tableName);

        /// <summary>
        /// Check if table exists
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// /// <returns>True if exists, else false</returns>
        public abstract bool ExistsTable(string tableName);

        /// <summary>
        /// Get table file name
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>Table file name</returns>
        public abstract string GetTableFileName(string tableName);

        /// <summary>
        /// Get table row length
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>Table row length</returns>
        public abstract int GetTableRowLength(string tableName);

        /// <summary>
        /// Get table attributes from catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>List of table attributes</returns>
        public abstract List<string> GetTableAttributes(string tableName);

        /// <summary>
        /// Create an attribute to table in catalog (column)
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <param name="dataType">Data type</param>
        /// <param name="isNull">Possible attribute to get null value</param>
        /// <param name="length">Length of the table attribute</param>
        public abstract void CreateTableAttribute(string tableName, string attributeName, DataType dataType, bool isNull, int length);

        /// <summary>
        /// Alter existing table attribute in catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <param name="newAttributeName">New name of the attribute</param>
        /// <param name="newDataType">New data type</param>
        /// <param name="newIsNull">New possible attribute to get null value</param>
        /// <param name="newLength">New length of attribute</param>
        public abstract void AlterTableAttribute(string tableName, string attributeName, string newAttributeName, DataType newDataType, bool newIsNull, int newLength);

        /// <summary>
        /// Drop an existing table attribute from catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        public abstract void DropTableAttribute(string tableName, string attributeName);

        /// <summary>
        /// Check if table attribute exists
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if exists, else false</returns>
        public abstract bool ExistsTableAttribute(string tableName, string attributeName);

        /// <summary>
        /// Get attribute data type
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>Type of data</returns>
        public abstract DataType GetTableAttributeDataType(string tableName, string attributeName);

        /// <summary>
        /// Can table attribute be null
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if attribute can be null, else false</returns>
        public abstract bool IsTableAttributeIsNull(string tableName, string attributeName);

        /// <summary>
        /// Get table attribute length
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>Length of the table attribute</returns>
        public abstract int GetTableAttributeLength(string tableName, string attributeName);

        /// <summary>
        /// Get primary key table attributes
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>List of primary key table attributes</returns>
        public abstract List<string> GetPrimaryKeyAttributes(string tableName);

        /// <summary>
        /// Set table attribute as primary key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the table attribute</param>
        public abstract void SetPrimaryKeyAttribute(string tableName, string attributeName);

        /// <summary>
        /// Unset table attribute as a primary key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        public abstract void UnsetPrimaryKeyAttribute(string tableName, string attributeName);

        /// <summary>
        /// Check if attribute is primary key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if is primary key, else false</returns>
        public abstract bool IsPrimaryKey(string tableName, string attributeName);

        /// <summary>
        /// Get unique key table attributes
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>List of unique key table attributes</returns>
        public abstract List<string> GetUniqueKeyAttributes(string tableName);

        /// <summary>
        /// Set table attribute as a unique key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        public abstract void SetUniqueKeyAttribute(string tableName, string attributeName);

        /// <summary>
        /// Unset table attribute as a unique key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        public abstract void UnsetUniqueKeyAttribute(string tableName, string attributeName);

        /// <summary>
        /// Check if attribute is unique key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if is unique key, else false</returns>
        public abstract bool IsUniqueKey(string tableName, string attributeName);

        /// <summary>
        /// Get foreign key table attributes
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>List of foreign key table attributes</returns>
        public abstract List<string> GetForeignKeyAttributes(string tableName);

        /// <summary>
        /// Set table attribute as a foreign key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <param name="referenceTableName">Name of the referenced table</param>
        /// <param name="referenceAttributeName">Name of the referenced attribute</param>
        public abstract void SetForeignKeyAttribute(string tableName, string attributeName,
            string referenceTableName, string referenceAttributeName);

        /// <summary>
        /// Unset table attribute as a foreign key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        public abstract void UnsetForeignKeyAttribute(string tableName, string attributeName);

        /// <summary>
        /// Check if attribute is foreign key
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if is foreign key, else false</returns>
        public abstract bool IsForeignKey(string tableName, string attributeName);

        /// <summary>
        /// Check if attribute is a foreign key reference
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if is foreign key reference, else false</returns>
        public abstract bool IsForeignKeyReference(string tableName, string attributeName);

        /// <summary>
        /// Get foreign key reference table
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="foreignKeyAttribute">Name of the attribute</param>
        /// <returns>Reference table name</returns>
        public abstract string GetForeignKeyReferenceTable(string tableName, string attributeName);

        /// <summary>
        /// Get foreign key reference attribute
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="foreignKeyAttribute">Name of the attribute</param>
        /// <returns>Reference attribute name</returns>
        public abstract string GetForeignKeyReferenceTableAttribute(string tableName, string foreignKeyAttribute);

        /// <summary>
        /// Get indexes of table
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <returns>Index names</returns>
        public abstract List<string> GetIndexes(string tableName);

        /// <summary>
        /// Create index to a table
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeNames">Names of the attributes</param>
        /// <param name="indexFileName">Name of the index file</param>
        /// <param name="indexType">Type of the index</param>
        /// <param name="isUnique">Index is unique</param>
        public abstract void CreateIndex(string tableName, string[] attributeNames, string indexFileName,
            IndexType indexType, bool isUnique);

        /// <summary>
        /// Drop an existing index from catalog
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="indexFileName">Name of the index file</param>
        public abstract void DropIndex(string tableName, string indexFileName);

        /// <summary>
        /// Check if table attribute has index
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>True if is foreign key reference, else false</returns>
        public abstract bool HasIndex(string tableName, string attributeName);

        /// <summary>
        /// Get index filename
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="indexAttribute">Index attribute</param>
        /// <returns>Filename of the index</returns>
        public abstract string GetIndexFileName(string tableName, string indexAttribute);

        /// <summary>
        /// Get index attributes
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="indexFileName">Name of the index file</param>
        /// <returns>Index attributes</returns>
        public abstract List<string> GetIndexAttributes(string tableName, string indexFileName);

        /// <summary>
        /// Get index type
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="indexFileName">Name of the index file</param>
        /// <returns>Type of index</returns>
        public abstract IndexType GetIndexType(string tableName, string indexFileName);

        /// <summary>
        /// Get index is unique
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="indexFileName">Name of the index file</param>
        /// <returns>True if index is unique, else false</returns>
        public abstract bool IsIndexUnique(string tableName, string indexFileName);

        /// <summary>
        /// Get index key length attribute
        /// </summary>
        /// <param name="tableName">Name of the table</param>
        /// <param name="indexFileName">Name of the index file</param>
        /// <returns>Length of the index key</returns>
        public abstract int GetIndexKeyLength(string tableName, string indexFileName);

    }
}
